package com.ruyidd.utils;

import cn.databytes.btw.*;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.ruyidd.entity.BartenderParams;
import com.ruyidd.entity.EmbeddedData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;
import org.thymeleaf.util.StringUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.List;

/**
 * @author tianxc
 */
public class BartenderUtils {

    private static Logger log =LoggerFactory.getLogger(BartenderUtils.class);

    private static volatile IBarTenderPrintService barTenderPrintService;

    public static ActiveXComponent getActiveXComponent() {
        ActiveXComponent btnApp = null;
        try {
            //要运行COM组件，需要先添加jacob包
            ComThread.InitSTA();
            btnApp = new ActiveXComponent("BarTender.Application");
            return btnApp;
        } catch (Exception e) {
            if(btnApp!=null){
                closeActiveXComponent(btnApp);
            }
            throw new RuntimeException("当前电脑未安装Bartender");
        }
    }

    /**
     * 关闭Bartender进程
     * @param btApp
     */
    public static void closeActiveXComponent(ActiveXComponent btApp){
        if(btApp!=null){
            //关闭Bartender进程
            Dispatch.call(btApp, "Quit", 0);
            btApp.safeRelease();
        }
        //释放线程
        ComThread.Release();
    }

    public static void checkBtwFileExisted(BartenderParams bartenderParams) throws Exception{
        String btwAbsolutePath = bartenderParams.getPath() + File.separator + bartenderParams.getBtwName();
        File btwFile = new File(btwAbsolutePath);
        if (!btwFile.exists()) {
            throw new RuntimeException("模板文件不存在:" + btwAbsolutePath);
        }
    }

    /**
     * 单实例 IBarTenderPrintService
     * @return
     */
    public static IBarTenderPrintService getBarTenderPrintService() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        if(barTenderPrintService!=null){
            /**
             * 判断是否可用
             */
            try {
                int processID = barTenderPrintService.getProcessID();
                log.info("当前Bartender进程ID:{}", processID);
            } catch (Exception e) {
                log.error("当前Bartender进程不可用，重新获取Bartender进程");
                //代表当前进程可能因为什么原因无法使用，重新获取Bartender进程
                barTenderPrintService = null;
            }
        }


        //第一次判断，如果instance不为null，不进入抢锁阶段，直接返回实例
        if(barTenderPrintService == null) {
            synchronized (BartenderUtils.class) {
                //抢到锁之后再次判断是否为null
                if(barTenderPrintService == null) {
                    barTenderPrintService = new BarTenderPrintService();
                }
            }
        }
        stopWatch.stop();
        log.info("获取Bartender打印对象耗时:{}", stopWatch.getTotalTimeSeconds());
        return barTenderPrintService;
    }

    public static void embeddedDataPrint(BartenderParams bartenderParams) throws Exception{
        try (IBarTenderPrintService printService = new BarTenderPrintService()) {
            String btwAbsolutePath = bartenderParams.getPath() + File.separator + bartenderParams.getBtwName();

            // 打开btw格式模板
            ITemplate template = printService.openTemplate(btwAbsolutePath, StringUtils.isEmpty(bartenderParams.getPrinter())?"":bartenderParams.getPrinter());
            /**
             * 嵌入式数据源
             */
            List<EmbeddedData> embeddedDataList = bartenderParams.getEmbeddedDataList();
            for (EmbeddedData embeddedData : embeddedDataList) {
                INamedSubStrings namedSubStrings = template.getNamedSubStrings();
                for (int i = 0; i < namedSubStrings.getCount(); i++) {
                    String name = namedSubStrings.getSubString(i + 1).getName();
                    template.setData(name, embeddedData.get(name));
                }
                // 打印参数配置
                IPrintSetup printSetup = template.getPrintSetup();
                // 设置打印份数
                if(bartenderParams.getIdenticalCopiesOfLabel()!=null&&bartenderParams.getIdenticalCopiesOfLabel()>0){
                    printSetup.setIdenticalCopiesOfLabel(bartenderParams.getIdenticalCopiesOfLabel());
                }

                if(bartenderParams.getNumberSerializedLabels()!=null&&bartenderParams.getNumberSerializedLabels()>0){
                    printSetup.setNumberSerializedLabels(bartenderParams.getNumberSerializedLabels());
                }
                // 打印输出
                template.printOut();
            }
        }
    }

    /**
     * 单实例的方式，bartender一直存在
     * @param bartenderParams
     * @throws Exception
     */
    public static void embeddedDataPrintSingleton(BartenderParams bartenderParams) throws Exception{
        String btwAbsolutePath = bartenderParams.getPath() + File.separator + bartenderParams.getBtwName();
        ITemplate template = getBarTenderPrintService().openTemplate(btwAbsolutePath, StringUtils.isEmpty(bartenderParams.getPrinter())?"":bartenderParams.getPrinter());
        /**
         * 嵌入式数据源
         */
        List<EmbeddedData> embeddedDataList = bartenderParams.getEmbeddedDataList();
        for (EmbeddedData embeddedData : embeddedDataList) {
            INamedSubStrings namedSubStrings = template.getNamedSubStrings();
            for (int i = 0; i < namedSubStrings.getCount(); i++) {
                String name = namedSubStrings.getSubString(i + 1).getName();
                template.setData(name, embeddedData.get(name));
            }
            // 打印参数配置
            IPrintSetup printSetup = template.getPrintSetup();
            // 设置打印份数
            if(bartenderParams.getIdenticalCopiesOfLabel()!=null&&bartenderParams.getIdenticalCopiesOfLabel()>0){
                printSetup.setIdenticalCopiesOfLabel(bartenderParams.getIdenticalCopiesOfLabel());
            }

            if(bartenderParams.getNumberSerializedLabels()!=null&&bartenderParams.getNumberSerializedLabels()>0){
                printSetup.setNumberSerializedLabels(bartenderParams.getNumberSerializedLabels());
            }
            // 打印输出
            template.printOut();
        }
    }

    public static void txtDataPrint(BartenderParams bartenderParams) throws Exception{
        BufferedWriter writer = null;
        try (IBarTenderPrintService printService = new BarTenderPrintService()) {
            String btwAbsolutePath = bartenderParams.getPath() + File.separator + bartenderParams.getBtwName();
            // 打开btw格式模板
            ITemplate template = printService.openTemplate(btwAbsolutePath, StringUtils.isEmpty(bartenderParams.getPrinter())?"":bartenderParams.getPrinter());
            // 设置使用数据模式
            // 设置使用数据模式
            template.setUseDatabase(true);
            template.setUseInputDataFile(true);
            IInputDataFile inputDataFile = template.getInputDataFile();
            String fileName = inputDataFile.getFileName();
            File file = new File(fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
            writer = new BufferedWriter(new FileWriter(file));
            /*
             * 获取数据，写入txt文件中
             */
            writer.write(bartenderParams.getTitle());
            writer.newLine();
            List<String> dataList = bartenderParams.getDataList();
            for (String data : dataList) {
                writer.write(data);
                writer.newLine();
            }
            writer.flush();
            writer.close();
            // 打印输出
            template.printOut();
        }finally {
            if(writer!=null){
                writer.close();
            }
        }
    }

    public static void txtDataPrintSingleton(BartenderParams bartenderParams) throws Exception{
        BufferedWriter writer = null;
        try {
            String btwAbsolutePath = bartenderParams.getPath() + File.separator + bartenderParams.getBtwName();
            // 打开btw格式模板
            ITemplate template = getBarTenderPrintService().openTemplate(btwAbsolutePath, StringUtils.isEmpty(bartenderParams.getPrinter())?"":bartenderParams.getPrinter());
            // 设置使用数据模式
            // 设置使用数据模式
            template.setUseDatabase(true);
            template.setUseInputDataFile(true);
            IInputDataFile inputDataFile = template.getInputDataFile();
            String fileName = inputDataFile.getFileName();
            File file = new File(fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
            writer = new BufferedWriter(new FileWriter(file));
            /*
             * 获取数据，写入txt文件中
             */
            writer.write(bartenderParams.getTitle());
            writer.newLine();
            List<String> dataList = bartenderParams.getDataList();
            for (String data : dataList) {
                writer.write(data);
                writer.newLine();
            }
            writer.flush();
            writer.close();
            // 打印输出
            template.printOut();
        }finally {
            if(writer!=null){
                writer.close();
            }
        }
    }
}
